package com.example.demo01;

import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

/**
 * 四则运算计算器
 */
public class Calculation {
    public static void main(String[] args) {
//        System.out.println(calculate3("(1+2)*4-3*(3*2-(2*2+5))+22/2",0).get("res"));
        int a=10,b=4,c=20,d=6;
        System.out.println(a++*b+c*--d);
    }
    /**
     * 没有括号： + - * /
     * @param str
     * @return
     */
    public static Double calculate1(String str){
        Deque<Double> stack=new LinkedList<>();
        char preSign='+';
        Double num=0.0;
        int len=str.length();
        for (int i = 0; i < len; ++i) {
            char ch = str.charAt(i);
            if (Character.isDigit(ch)){
                num=num*10+(ch-'0');
            }
            if (!Character.isDigit(ch) && ch!=' ' || i==len-1){
                switch (preSign){
                    case '+':
                        stack.push(num);
                        break;
                    case '-':
                        stack.push(-num);
                        break;
                    case '*':
                        stack.push(stack.pop()*num);
                        break;
                    default:
                        stack.push(stack.pop()/num);
                        break;
                }
                preSign=ch;
                num=0.0;
            }
        }
        Double result=0.0;
        while (!stack.isEmpty()){
            result+=stack.pop();
        }
        return result;
    }

    /**
     * 有+-和括号
     * @param str
     * @return
     */
    public static int calculate2(String str){
        Deque<Integer> stack=new LinkedList<>();
        int result=0;
        int num=0;
        int len=str.length();
        int sign=1;
        stack.push(1);
        for (int i = 0; i < len; i++) {
            char ch=str.charAt(i);
            if (Character.isDigit(ch)){
                num=num*10+(ch-'0');
            }
            if (!Character.isDigit(ch) && ch!=' ' || i==len-1){
                result+=sign*num;
                switch (ch){
                    case '+':
                        sign=stack.peek();
                        break;
                    case '-':
                        sign=-stack.peek();
                        break;
                    case '(':
                        stack.push(sign);
                        break;
                    default:
                        stack.pop();
                }
                num=0;
            }
        }
        return result;
    }


    public static Map<String, Integer> calculate3(String str,int i){
        Deque<Integer> stack=new LinkedList<>();
        Map<String, Integer> map=new HashMap<>();
        int result=0;
        int num=0;
        char preSign='+';
        for (;i < str.length(); i++) {
            char ch=str.charAt(i);
            if (Character.isDigit(ch)){
                num=num*10+(ch-'0');
            }
            if (ch=='('){
                Map<String, Integer> res = calculate3(str, i + 1);
                num= res.get("res");
                i=res.get("offset");
            }
            if (!Character.isDigit(ch) && ch!=' ' && ch!='(' || i==str.length()-1){
                switch (preSign){
                    case '+':
                        stack.push(num);
                        break;
                    case '-':
                        stack.push(-num);
                        break;
                    case '*':
                        stack.push(stack.pop()*num);
                        break;
                    default:
                        stack.push(stack.pop()/num);
                        break;
                }
                preSign=ch;
                num=0;
            }
            if (ch==')'){
                break;
            }
        }
        while (!stack.isEmpty()){
            result+=stack.pop();
        }
        map.put("res",result);
        map.put("offset",i);
        return map;
    }
}
